//
//  STPageView.swift
//  Story
//
//  Created by 汤泽川 on 2019/4/13.
//  Copyright © 2019 汤泽川. All rights reserved.
//

import Foundation
import UIKit
import SnapKit

protocol STPageViewDelegate : NSObjectProtocol {
    func didScrollToPage(currentPage : Int)
}

class STPageView:UIView, UIScrollViewDelegate {
    
    public weak var pageDelegate : STPageViewDelegate?
    
    private var pages : [UIView]?
    private(set) var currentIndex = 0
    private let scrollView = UIScrollView()
    convenience init(pages : [UIView]) {
        self.init(frame: CGRect.zero)
        self.pages = pages
        setupPages()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.scrollView.isPagingEnabled = true
        self.scrollView.delegate = self
        self.scrollView.showsVerticalScrollIndicator = false
        self.scrollView.showsHorizontalScrollIndicator = false
        self.addSubview(scrollView)
        self.currentIndex = 0
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func updateConstraints() {
        super.updateConstraints()
        self.scrollView.snp.updateConstraints { (make) in
            make.edges.equalToSuperview()
        }
    }
    
    public func updatePages(pages : [UIView]) {
        if self.pages == nil {
            self.pages = pages
        } else {
            for page in self.pages! {
                page.removeFromSuperview()
            }
            self.pages!.removeAll()
            self.pages = pages
        }
        setupPages()
        currentIndex = 0
        self.scrollView.contentOffset = CGPoint.zero
    }
    
    private func setupPages() {
        guard let pages = pages  else {
            return
        }
        
        var currentPage : UIView = self.scrollView
        for (index, page) in pages.enumerated() {
            self.scrollView.addSubview(page)
            page.snp.remakeConstraints { (make) in
                if index == 0 {
                    make.left.equalToSuperview()
                } else {
                    make.left.equalTo(currentPage.snp.right)
                }
                make.top.bottom.height.width.equalToSuperview()
                if index == pages.count - 1 {
                    make.right.equalToSuperview()
                }
            }
            currentPage = page
        }
    }
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        
        let contentOffset = targetContentOffset.pointee
        
        let index = Int(ceil(contentOffset.x / scrollView.width))
        if index != currentIndex {
            currentIndex = index
            self.pageDelegate?.didScrollToPage(currentPage: currentIndex)
        }
    }
    
    public func scrollToPage(pageIndex : Int) {
        guard let pages = pages else {
            return
        }
        if pageIndex == currentIndex {
            return
        }
        
        func scrollToPoint(point : CGPoint, animate : Bool, complete : (() -> Void)? = nil) {
            if animate == false {
                self.scrollView.contentOffset = point
                complete?()
            } else {
                UIView.animate(withDuration:0.25, animations: {
                    self.scrollView.contentOffset = point
                }) { _ in
                    complete?()
                }
            }
        }
        
        var lastPageIndex = currentIndex
        let frameImage = UIImage.imageFrom(view: pages[lastPageIndex])
        currentIndex = max(0, pageIndex)
        currentIndex = min(pageIndex, pages.count - 1)
        if currentIndex - lastPageIndex >= 2 {
            lastPageIndex = currentIndex - 1
        } else if lastPageIndex - currentIndex >= 2 {
            lastPageIndex = currentIndex + 1
        }
        let imageView = UIImageView(frame: pages[lastPageIndex].bounds)
        imageView.image = frameImage
        pages[lastPageIndex].addSubview(imageView)
        scrollToPoint(point: CGPoint(x: CGFloat(lastPageIndex) * self.scrollView.width, y: 0), animate: false)
        scrollToPoint(point: CGPoint(x: CGFloat(currentIndex) * self.scrollView.width, y: 0), animate: true) {
            imageView.removeFromSuperview()
        }
    }
    
}
